import 'package:flutter/material.dart';

import 'package:get/get_state_manager/get_state_manager.dart';
import 'package:get/instance_manager.dart';
import 'package:flutter_widgets_pc/resources/kq_theme_colors.dart';

///抽象封装
class KqSectionListView<E> extends StatefulWidget {
  ///分区数
  final int section;

  ///是否显示索引,默认false,若要显示索引且无需自定义时，可让参数对象类集成KqSeactinIndexModel，并使用KqSectionIndexState中方法获取分区对象
  final bool isShowIndex;

  ///行高是否相同默认false
  final bool isSameHeight;

  ///分区头部是否吸顶，true:必须传入分区高和行高，不可以使用自适应，isSameHeight必须设置为true
  final bool isFixtop;

  ///索引列表,true:必须传入分区高和行高，不可以使用自适应，isSameHeight必须设置为true
  final List? indexList;

  ///单个索引的高度的最大高度,默认为20
  final double? indexHeight;

  ///索引区间宽度，默认为20
  final double? indexWidth;

  /*索引区间的最大长度,不设置则索引区间为sectionView的高度，每个索引高度为indexHeight，
  设置后每个索引的最大高度indexHeight，超屏后每个高度会自动缩放*/
  final double? indexListHeigt;

  ///索引文字大小，默认为12
  final double? indexFont;

  ///索引文字颜色，默认为999999
  final Color? indexTextColor;

  ///区头高度，若设置吸顶必须设置
  final double sectionHeight;

  ///行高isSameHeight=true时设置才会被使用，默认为44
  final double Function(int section)? rowHeight;

  ///对应section分区内的内容数组
  final List<E> Function(int section) itemList;

  ///列表头部UI
  final Widget Function()? listHeaderBuilder;

  ///列表尾部UI
  final Widget Function()? listFooterBuilder;

  ///分组头部UI
  final Widget Function(int section) headerBuilder;

  ///cell的对应UI
  final Widget Function(int section, int row, E object) itemBuilder;

  ///有无使用SectionShareData共享数据，默认为No
  final bool? isShareData;

  ///键盘事件
  final ScrollViewKeyboardDismissBehavior keyboardDismissBehavior;

  const KqSectionListView({
    Key? key,
    this.indexList,
    this.indexHeight,
    this.indexWidth,
    this.indexFont,
    this.indexTextColor,
    this.isShowIndex = false,
    required this.section,
    this.isSameHeight = false,
    this.rowHeight,
    this.indexListHeigt,
    this.sectionHeight = 0,
    this.isFixtop = false,
    required this.headerBuilder,
    required this.itemBuilder,
    this.isShareData = false,
    required this.itemList,
    this.listHeaderBuilder,
    this.listFooterBuilder,
    this.keyboardDismissBehavior = ScrollViewKeyboardDismissBehavior.manual,
  }) : super(key: key);

  @override
  State<KqSectionListView> createState() => _KqSectionListViewState<E>();
}

class _KqSectionListViewState<E> extends State<KqSectionListView<E>> {
  List<Widget> slivers = [];
  ListService service = Get.put<ListService>(ListService());
  ScrollController controller = ScrollController();
  final GlobalKey globalKey = GlobalKey();

  ///分区view数组
  List<Widget> headList = [];

  ///滚动方向false向下
  bool scrollTop = false;

  ///分区起始点数组
  List offsetHeadList = [];

  ///进入或离开seaction区间
  bool isShowFirst = true;

  ///当前索引所在位置
  int nowIndex = 0;

  ///最后一页的顶部位置
  double lastOffset = 0;

  ///最后一页顶部的index
  int lastIndex = 0;

  ///是否是点击触发
  bool isDidClick = false;

  double indexH = 0;
  double indexW = 0;

  @override
  void initState() {
    super.initState();
    service.nowSection = 0;
    service.maxSectionHeight = widget.sectionHeight;
    double scorellOffset = 0;
    controller.addListener(() {
      if (scorellOffset - controller.offset > 0) {
        scrollTop = false;
      } else {
        scrollTop = true;
      }
      scorellOffset = controller.offset;
      setScrollAnimation(false);
    });
  }

  setScrollAnimation(bool isEnd) {
    if (widget.isFixtop) {
      for (int i = 0; i < offsetHeadList.length; i++) {
        double seactionY = offsetHeadList[i];
        if (i == 0) {
          isShowFirst = true;
          if (controller.offset < seactionY + widget.sectionHeight &&
              controller.offset > seactionY) {
            service.nowSection = 0;
            service.maxSectionHeight = widget.sectionHeight;
            if (!scrollTop) {
              nowIndex = service.nowSection;
            } else {
              if (!isDidClick) {
                nowIndex = service.nowSection;
              }
            }
            service.update();
            break;
          } else if (controller.offset < 0) {
            isShowFirst = false;
            service.update();
            break;
          } else {
            if (service.maxSectionHeight != widget.sectionHeight) {
              service.maxSectionHeight = widget.sectionHeight;
              service.update();
            }
          }
        } else if (controller.offset > seactionY - widget.sectionHeight) {
          if (scrollTop) {
            if (controller.offset < seactionY) {
              service.maxSectionHeight = seactionY - controller.offset;
              service.nowSection = i - 1;
              if (!isDidClick) {
                nowIndex = service.nowSection;
              }
              service.update();
              break;
            } else {
              if (controller.offset <
                      offsetHeadList[i + 1] - widget.sectionHeight &&
                  controller.offset > seactionY) {
                service.nowSection = i;
                if (!isDidClick) {
                  nowIndex = service.nowSection;
                }
                service.maxSectionHeight = widget.sectionHeight;
                service.update();
                break;
              }
            }
          } else {
            if (controller.offset < seactionY) {
              service.maxSectionHeight = seactionY - controller.offset;
              service.nowSection = nowIndex = i - 1;
              if (i == 0) {
                service.nowSection = nowIndex = 0;
              }
              service.update();
              break;
            } else {
              if (service.maxSectionHeight != widget.sectionHeight) {
                service.maxSectionHeight = widget.sectionHeight;
                service.update();
              }
            }
          }
        } else {
          if (isEnd) {
            isDidClick = false;
            service.update();
          }
        }
      }
    }
  }

  @override
  void dispose() {
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return _buildBody();
  }

  ///索引区
  Widget _buildListIndexView() {
    return Visibility(
      visible: widget.isShowIndex,
      child: Container(
        margin: EdgeInsets.only(right: 16),
        width: indexW,
        alignment: Alignment.centerRight,
        child: GestureDetector(
          onTapDown: (details) {
            double indexDouble = details.localPosition.dy / indexH;
            int index = indexDouble.truncate();
            nowIndex = index;
            double nowOffst = offsetHeadList[index];
            double? myHeight = globalKey.currentContext?.size!.height;
            lastOffset = offsetHeadList.last - myHeight;
            for (int j = widget.section; j >= 0; j--) {
              double yPoint = offsetHeadList[j];
              if (yPoint < lastOffset) {
                lastIndex = j;
                break;
              }
            }
            service.nowSection = nowOffst < lastOffset ? index : lastIndex;
            isDidClick = true;
            controller.jumpTo(nowOffst < lastOffset
                ? offsetHeadList[index]
                : lastOffset > 0
                    ? lastOffset
                    : 0);
            service.update();
          },
          onVerticalDragUpdate: (details) {
            double indexDouble = details.localPosition.dy / indexH;
            int index = indexDouble.truncate();
            if (index >= widget.section) {
              index = widget.section - 1;
            } else if (indexDouble < 0) {
              index = 0;
            } else {
              index = index;
            }
            if (nowIndex != index) {
              nowIndex = index < offsetHeadList.length - 1
                  ? index
                  : offsetHeadList.length - 1;
              double nowOffst = offsetHeadList[index];
              double? myHeight = globalKey.currentContext?.size!.height;
              lastOffset = offsetHeadList.last - myHeight;
              for (int j = widget.section; j >= 0; j--) {
                double yPoint = offsetHeadList[j];
                if (yPoint < lastOffset) {
                  lastIndex = j;
                  break;
                }
              }
              service.nowSection = nowOffst < lastOffset ? index : lastIndex;
              controller.jumpTo(nowOffst < lastOffset
                  ? offsetHeadList[index]
                  : lastOffset > 0
                      ? lastOffset
                      : 0);
              service.update();
            }
          },
          child: Container(
            color: KqThemeColors.bgTransparent,
            height: widget.indexListHeigt,
            child: GetBuilder(
              init: service,
              builder: (controller) => ListView.builder(
                itemCount:
                    widget.indexList != null ? widget.indexList!.length : 0,
                itemExtent: indexH,
                physics: const NeverScrollableScrollPhysics(),
                shrinkWrap: true,
                itemBuilder: ((context, index) {
                  return Container(
                    alignment: Alignment.center,
                    width: indexW,
                    decoration: BoxDecoration(
                      color: index == nowIndex
                          ? KqThemeColors.textLightBlue
                          : KqThemeColors.bgTransparent,
                      borderRadius:
                          BorderRadius.all(Radius.circular(indexH / 2)),
                    ),
                    child: Text(
                      widget.indexList!.isNotEmpty
                          ? widget.indexList![index]
                          : "",
                      style: TextStyle(
                          fontSize: widget.indexFont ?? 12,
                          color: index == nowIndex
                              ? KqThemeColors.bgWhite
                              : widget.indexTextColor ??
                                  KqThemeColors.textLightBlue),
                    ),
                  );
                }),
              ),
            ),
          ),
        ),
      ),
    );
  }

  Widget _buildBody() {
    if (widget.isFixtop) {
      return Stack(
        alignment: Alignment.topRight,
        key: globalKey,
        children: [
          NotificationListener(
            onNotification: (ScrollNotification notification) {
              if (notification is ScrollEndNotification) {
                setScrollAnimation(true);
                return true;
              }
              return false;
            },
            child: CustomScrollView(
              controller: controller,
              keyboardDismissBehavior: widget.keyboardDismissBehavior,
              slivers: getSlivers(),
            ),
          ),
          GetBuilder<ListService>(
            init: service,
            builder: (controller) => Visibility(
              visible: headList.isNotEmpty && isShowFirst,
              child: Container(
                constraints:
                    BoxConstraints(maxHeight: service.maxSectionHeight),
                child: headList.isEmpty
                    ? Container()
                    : headList[service.nowSection],
              ),
            ),
          ),
          _buildListIndexView(),
        ],
      );
    } else {
      return Stack(
        alignment: Alignment.topRight,
        key: globalKey,
        children: [
          CustomScrollView(
            keyboardDismissBehavior: widget.keyboardDismissBehavior,
            slivers: getSlivers(),
            controller: controller,
          ),
          _buildListIndexView(),
        ],
      );
    }
  }

  ///listView头部区域
  Widget _tableViewHeaderView(Widget child) {
    return SliverToBoxAdapter(
      child: child,
    );
  }

  ///listView头部区域
  Widget _tableViewFooterView(Widget child) {
    return SliverToBoxAdapter(
      child: child,
    );
  }

  ///Section头部区域布局
  Widget _buildHeader({required int section, required Widget child}) {
    Widget build = widget.isFixtop || widget.isShowIndex
        ? SizedBox(
            height: widget.sectionHeight, width: double.infinity, child: child)
        : child;
    headList.add(build);
    return SliverToBoxAdapter(child: build);
  }

  Widget _buildSliverList(
      {required int section, required double height, required List<E> list}) {
    if (widget.isSameHeight) {
      return SliverFixedExtentList(
          delegate: SliverChildBuilderDelegate(
              (_, int index) => widget.itemBuilder(section, index, list[index]),
              childCount: list.length),
          itemExtent: height);
    } else {
      return SliverList(
        delegate: SliverChildBuilderDelegate(
            (_, int index) => widget.itemBuilder(section, index, list[index]),
            childCount: list.length),
      );
    }
  }

  List<Widget> getSlivers() {
    indexH = widget.indexHeight ?? 20;
    indexW = widget.indexWidth ?? 20;
    if (widget.indexListHeigt != null) {
      if (indexH * widget.section > widget.indexListHeigt!) {
        indexH = (widget.indexListHeigt! / widget.section).truncateToDouble();
        indexW = indexH;
      }
    }
    slivers = [];
    if (widget.listHeaderBuilder != null) {
      slivers.add(_tableViewHeaderView(widget.listHeaderBuilder!()));
    }
    double sectionOffsetY = 0;
    offsetHeadList = [sectionOffsetY];
    headList = [];
    for (int i = 0; i < widget.section; i++) {
      List<E> rowList = widget.itemList(i);
      double rowHeights = 44;
      if (widget.rowHeight != null) {
        rowHeights = widget.rowHeight!(i);
      }
      sectionOffsetY =
          sectionOffsetY + widget.sectionHeight + rowList.length * rowHeights;
      offsetHeadList.add(sectionOffsetY);
      slivers.add(_buildHeader(
        section: i,
        child: widget.headerBuilder(i),
      ));
      slivers.add(_buildSliverList(
          section: i,
          height: rowHeights,
          list: rowList.whereType<E>().toList()));
    }
    if (widget.listFooterBuilder != null) {
      slivers.add(_tableViewFooterView(widget.listFooterBuilder!()));
    }
    return slivers;
  }
}

// typedef SliverHeaderBuilder = Widget Function(
//     BuildContext context, double shrinkOffset, bool overlapsContent);

// class SliverHeaderDelegate extends SliverPersistentHeaderDelegate {
//   // child 为 header
//   SliverHeaderDelegate({
//     required this.maxHeight,
//     this.minHeight = 0,
//     required Widget child,
//   })  : builder = ((a, b, c) => child),
//         assert(minHeight <= maxHeight && minHeight >= 0);

//   //最大和最小高度相同
//   SliverHeaderDelegate.fixedHeight({
//     required double height,
//     required Widget child,
//   })  : builder = ((a, b, c) => child),
//         maxHeight = height + 1,
//         minHeight = height;

//   //需要自定义builder时使用
//   SliverHeaderDelegate.builder({
//     required this.maxHeight,
//     this.minHeight = 0,
//     required this.builder,
//   });

//   final double maxHeight;
//   final double minHeight;
//   final SliverHeaderBuilder builder;

//   @override
//   Widget build(
//     BuildContext context,
//     double shrinkOffset,
//     bool overlapsContent,
//   ) {
//     Widget child = builder(context, shrinkOffset, overlapsContent);
//     //测试代码：如果在调试模式，且子组件设置了key，则打印日志
//     assert(() {
//       if (child.key != null) {
//         print('${child.key}: shrink: $shrinkOffset，overlaps:$overlapsContent');
//       }
//       return true;
//     }());
//     // print('${child.key}: shrink: $shrinkOffset，overlaps:$overlapsContent,section:${section.toString()}');
//     return SizedBox.expand(child: child);
// // 让 header 尽可能充满限制的空间；宽度为 Viewport 宽度，
//     // 高度随着用户滑动在[minHeight,maxHeight]之间变化。
//     // return SizedBox(height: maxHeight - shrinkOffset, child: child);
//   }

//   @override
//   double get maxExtent => maxHeight;

//   @override
//   double get minExtent => minHeight;

//   @override
//   bool shouldRebuild(SliverHeaderDelegate oldDelegate) {
//     return oldDelegate.maxExtent != maxExtent ||
//         oldDelegate.minExtent != minExtent;
//   }
// }

class ListService extends GetxController {
  late int nowSection = 0;
  late double maxSectionHeight = 0;
}


///数据共享方式
/*
class KqSectionShareData<H, E> extends InheritedWidget {
  final List<H> dataList;

  ///监听第一次变化
  final int flag;

  const KqSectionShareData({
    Key? key,
    required this.dataList,
    required Widget child,
    required this.flag,
  }) : super(key: key, child: child);

  //定义一个便捷方法，方便子树中的widget获取共享数据
  static KqSectionShareData? of(BuildContext context) {
    return context.dependOnInheritedWidgetOfExactType<KqSectionShareData>();
  }

  //该回调决定当data发生变化时，是否通知子树中依赖data的Widget重新build
  @override
  bool updateShouldNotify(KqSectionShareData oldWidget) {
    bool isRolad = (oldWidget.dataList != dataList);
    if (oldWidget.flag == 0) {
      isRolad = true;
    }
    return isRolad;
  }
}
*/